package repository;

import annotation.DependencyInjection;
import annotation.Singleton;
import database.RelationDatabase;
import entity.Relation;
import enums.RelationState;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Singleton
public class RelationRepository {
    private RelationDatabase database;

    @DependencyInjection
    public RelationRepository(RelationDatabase database) {
        this.database = database;
    }

    public void startWrite() {
        database.startWrite();
    }

    public void endWrite() {
        database.endWrite();
    }

    public void startRead() {
        database.startRead();
    }

    public void endRead() {
        database.endRead();
    }

    public boolean updateTimestamp(String hostUsername, String guestUsername, LocalDateTime timestamp) {
        Optional<Relation> result = database.getList().stream().filter(
            relation -> relation.getHostUsername().equals(hostUsername) && relation.getGuestUsername().equals(guestUsername)).findAny();
        if (!result.isPresent()) {
            return false;
        }

        result.get().setTimestamp(timestamp);
        return true;
    }

    public Relation get(String hostUsername, String guestUsername) {
        Relation result = database.getList().stream().filter(relation ->
                relation.getHostUsername().equals(hostUsername) && relation.getGuestUsername().equals(guestUsername)).
            findAny().orElse(null);
        if (result == null) {
            return null;
        }
        return new Relation(result);
    }

    public List<String> getAllFriendUsernames(String username) {
        return database.getList().stream().filter(relation -> relation.getHostUsername().equals(username) &&
                relation.getState().equals(RelationState.Friend)).map(Relation::getGuestUsername).
            collect(Collectors.toList());
    }

    public List<String> getAllApplyingUsernames(String guestUsername) {
        return database.getList().stream().filter(relation -> relation.getGuestUsername().equals(guestUsername) &&
                relation.getState().equals(RelationState.Applying)).map(Relation::getHostUsername).
            collect(Collectors.toList());
    }

    public boolean updateState(String hostUsername, String guestUsername, RelationState state) {
        Optional<Relation> result = database.getList().stream().filter(
            relation -> relation.getHostUsername().equals(hostUsername) && relation.getGuestUsername().equals(guestUsername)).findAny();
        if (!result.isPresent()) {
            return false;
        }
        Relation relation = result.get();
        relation.setState(state);
        return true;
    }

    public void add(Relation relation) {
        database.getList().add(relation);
    }
}
